#!/usr/bin/env python

import os
import logging
import wsgiref.handlers
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from util.sessions import Session
from google.appengine.ext import db

import re
from util.regexFuncs import *
import copy

version = '1.0.3'
message = ''


defaultVals = {'version' : version, 'message': message}


# A helper to do the rendering and to add the necessary
# variables for the _base.html template
def doRender(handler, tname = 'index.html', values = { }):
  temp = os.path.join(
      os.path.dirname(__file__),
      'templates/' + tname)
  if not os.path.isfile(temp):
    return False

  # Check to see if we are supposed to be rendering a non-HTML file.
  binary = False
  if temp.endswith(".jpg") or temp.endswith(".jpeg"):
    handler.response.headers['Content-Type'] = 'image/jpeg'
    binary = True
  elif temp.endswith('.png'):
    handler.response.headers['Content-Type'] = 'image/png'
    binary = True

  if binary:
    outstr = open(temp, "rb").read()
    handler.response.out.write(unicode(outstr))
    return True

  # Make a copy of the dictionary and add the path and session
  newval = dict(values)
  newval['path'] = handler.request.path
  handler.session = Session()
  if 'username' in handler.session:
     newval['username'] = handler.session['username']

  outstr = template.render(temp, newval)
  handler.response.out.write(unicode(outstr))
  return True

def renderRegexHTML(matchresult, matches, groups, groupdict, message = True, matchTitle = "Matches"):   
    resulttext = matchresult
  
    if matches != None and len(matches) >= 1:
           
        resulttext += '<h3>' + matchTitle + '</h3>'
        resulttext += '<ol>'  
        i = 1
    
        for m in matches:
            resulttext += '<li> ' + m + '</li>'
            i += 1 #Adds 1 to i
            
        resulttext += '</ol>'
     
    else:
         if message:
             resulttext += '<br>No matches'
      
    # Render the numbered captures 
    if groups != None and len(groups) >= 1:
        resulttext += '<br><h3>Captures</h3>'
        resulttext += '<ol>'
        i = 1
        
        for g in groups:
            resulttext += '<li>' + g + '</li>'
            i += 1 #Adds 1 to i
            
        resulttext += '</ol>'
            
    # Render the named captures
    if groupdict:
        resulttext += '<br><h3>Named Captures</h3>'
        
        for groupname, grouptext in groupdict.items():
            resulttext += '<br>' + codify(groupname) + ': ' + codify(grouptext)

    return resulttext


  
def handleFlags(request):
    flags = 0
    flaglist = 'imsxg'
    flagdict = {}

    for flag in flaglist:
        if request.get(flag, 'false') == 'checked':
            flagdict[flag + 'checked'] = 'checked="checked"'
            
            if flag != 'g':
                FLAG = flag.upper()
                flags += re.__dict__[FLAG]
        
    return flags, flagdict



class RegexMatchHandler(webapp.RequestHandler):

    def get(self):
        doRender(self, 'regexmatch.html', defaultVals)
  
    def post(self):
        newVals = copy.copy(defaultVals)
        matchpattern = self.request.get('matchpattern', '')
        texttomatch = self.request.get('texttomatch', '')

        if not (matchpattern and texttomatch):
            self.get()
            return

        else:
            flags, flagdict = handleFlags(self.request)
            newVals.update(flagdict)
            count = self.request.get('count', '0')

            if count == '' or self.request.get('g') == 'checked':
                actualcount = 0
            else:
                actualcount = max(0, int(count))
        
            matchresult, matches, groups, groupdict = matchText(matchpattern, texttomatch, flags=flags, count=actualcount)

            if matches != None and groups != None and groupdict != None:
                resulttext = renderRegexHTML(matchresult, matches, groups, groupdict)
            else:
                resulttext = matchresult
                
            newVals.update({'matchpattern' : matchpattern,
                            'texttomatch' : texttomatch, 
                            'resulttext' : resulttext,
                            'count' : str(count)})

            doRender(self, 'regexmatch.html', newVals)


class RegexReplaceHandler(webapp.RequestHandler):

    def get(self):
        doRender(self, 'regexreplace.html', defaultVals)
  
    def post(self):
        newVals = copy.copy(defaultVals)
        matchpattern = self.request.get('matchpattern', '')
        replpattern = self.request.get('replpattern', '')
        texttomatch = self.request.get('texttomatch', '')
        if not (matchpattern and replpattern and texttomatch):
            self.get()
            return

        else:
            flags, flagdict = handleFlags(self.request)
            newVals.update(flagdict)
            
            count = self.request.get('count', '0')

            if count == '' or self.request.get('g') == 'checked':
                actualcount = 0
            else:
                actualcount = max(0, int(count))
        

            represult, nsubs, groups, groupdict = replaceText(matchpattern, 
                                                              replpattern, 
                                                              texttomatch,
                                                              flags=flags,
                                                              count = actualcount)
            if nsubs != None:
                resulttext = represult + '<br><p id="nsubs">' + \
                    str(nsubs) + ' substitutions</p>' + renderRegexHTML('', [], groups, groupdict, False)
            else:
                resulttext = represult

            newVals.update({'matchpattern' : matchpattern,
                            'replpattern': replpattern,
                            'texttomatch' : texttomatch,
                            'resulttext' : resulttext,
                            'count' : str(count)})

            doRender(self, 'regexreplace.html', newVals)
                     

class RegexSplitHandler(webapp.RequestHandler):

    def get(self):
        doRender(self, 'regexsplit.html', defaultVals)
  
    def post(self):
        newVals = copy.copy(defaultVals)
        matchpattern = self.request.get('matchpattern', '')
        texttomatch = self.request.get('texttomatch', '')
        if not (matchpattern and texttomatch):
            self.get()
            return

        else:
            flags, flagdict = handleFlags(self.request)
            newVals.update(flagdict)

            count = self.request.get('count', '0')

            if count == '' or self.request.get('g') == 'checked':
                actualcount = 0
            else:
                actualcount = max(0, int(count))
        

            splitgroups, groups, groupdict = splitText(matchpattern, texttomatch, flags=flags,
                                                       count=actualcount)
        
            if not isinstance(groups, str):
                resulttext = renderRegexHTML('', splitgroups, groups, groupdict, matchTitle = "Groups")
            else:
                resulttext = groups

            newVals.update({'matchpattern' : matchpattern,
                            'texttomatch' : texttomatch,
                            'resulttext' : resulttext,
                            'count' : str(count)})

            doRender(self, 'regexsplit.html', newVals)
                         


class MainHandler(webapp.RequestHandler):

    def get(self):
        vals = {'version' : version}
        if doRender(self,self.request.path, vals) :
            return
        doRender(self,'index.html', vals)

def main():
    application = webapp.WSGIApplication(
        [('/regexmatch\.htm.*', RegexMatchHandler),
         ('/regexreplace\.htm.*', RegexReplaceHandler),
         ('/regexsplit\.htm.*', RegexSplitHandler),
         ('/.*', MainHandler)],
        debug=True)
    wsgiref.handlers.CGIHandler().run(application)


if __name__ == '__main__':
    main()
